/**
 * @file object.h
 * @brief 对象池对象的基类，便于数据和接口分离
 */
#ifndef TIANYU_COMMON_OBJECT_H_
#define TIANYU_COMMON_OBJECT_H_


#define OBJ_ID_BITS (24)  // 对象ID的范围最大为2^^24,即16777216个
#define INVALID_OBJ_ID	( 0 )// 无效对象ID

#include "common_define.h"

typedef int32_t OBJ_ID_TYPE;


namespace common
{

	class CObj
	{
	public:
		/**
		 * @brief CObj 只在初始化模式下, 设置id_为非法值
		 */
		CObj( )
		{
		}

		/**
		 * @brief ~CObj
		 */
		virtual ~CObj( )
		{
			// 在析构的时候，设置id_，可以保证内存中id_数据的合法性
			// 这是因为有时候需要通过id来访问数据，而在共享内存中的数据，并不会真正析构
			id_ = INVALID_OBJ_ID;
		}

		/**
		 * @brief get_id 获得对象ID
		 *
		 * @return
		 */
		OBJ_ID_TYPE get_id( ) const
		{
			return id_;
		}

		/**
		 * @brief set_id 设置对象ID
		 *
		 * @param id
		 */
		void set_id( OBJ_ID_TYPE id )
		{
			id_ = id;
		}

		/**
		 * @brief ID2TYPE 获得对象的类型
		 *
		 * @param id
		 *
		 * @return
		 */
		static int ID2TYPE( int id )
		{
			// 先移位然后计算结果，可以避免得到负数
			return ( id >> OBJ_ID_BITS ) & 0X000000FF;
		}

		/**
		 * @brief valid 判断object是否合法,由于开启异常处理不太方便，在这里加上这个函数。如果构造函数失败，只需要设置id =INVALID_OBJ_ID即可.这种方式虽然比较丑类,但是可以比较有效的不使用异常来处理构造函数中发现的错误
		 *
		 * @return
		 */
		bool valid( ) const
		{
			return INVALID_OBJ_ID != id_;
		}

		/**
		 * @brief invalid 设置对象非法
		 */
		void invalid( )
		{
			id_ = INVALID_OBJ_ID;
		}

	private:
		/**
		 * @brief 所有对象的唯一标识
		 */
		OBJ_ID_TYPE id_;

	};

}

#endif

